// Default Parameters (默认参数) 示例
// 演示 Pascal 中默认参数的用法
program p_14_default_parameters;

{$mode objfpc}{$H+}
// {$mode objfpc} 启用 Object Pascal 模式，支持默认参数
// {$H+} 启用长字符串支持（AnsiString）

// 引入单元文件
uses
  SysUtils;  // 系统工具单元，包含常用的系统函数

// 1. 带默认参数的过程 - 显示消息
procedure DisplayMessage(msg: String; repeatCount: Integer = 1);
var
  i: Integer;
begin
  for i := 1 to repeatCount do
    WriteLn(msg);
end;

// 2. 多个默认参数的过程 - 绘制矩形
procedure DrawRectangle(width, height: Integer; symbol: Char = '*'; filled: Boolean = False);
var
  i, j: Integer;
begin
  WriteLn('绘制一个 ', width, 'x', height, ' 的矩形，使用符号 ''', symbol, '''');
  
  if filled then
  begin
    // 绘制填充矩形
    for i := 1 to height do
    begin
      for j := 1 to width do
        Write(symbol);
      WriteLn;
    end;
  end
  else
  begin
    // 绘制空心矩形
    // 第一行
    for j := 1 to width do
      Write(symbol);
    WriteLn;
    
    // 中间行
    if height > 2 then
    begin
      for i := 2 to height - 1 do
      begin
        Write(symbol);
        for j := 2 to width - 1 do
          Write(' ');
        WriteLn(symbol);
      end;
    end;
    
    // 最后一行
    if height > 1 then
    begin
      for j := 1 to width do
        Write(symbol);
      WriteLn;
    end;
  end;
  WriteLn;
end;

// 3. 带默认参数的函数 - 计算折扣价格
function CalculateDiscountedPrice(originalPrice: Real; discountPercent: Real = 0.0; taxRate: Real = 0.0): Real;
var
  discountedPrice: Real;
begin
  discountedPrice := originalPrice * (1 - discountPercent / 100);
  CalculateDiscountedPrice := discountedPrice * (1 + taxRate / 100);
end;

// 4. 使用常量作为默认参数
const
  DEFAULT_NAME = '未知用户';
  DEFAULT_AGE = 0;
  
procedure DisplayUserInfo(name: String = DEFAULT_NAME; age: Integer = DEFAULT_AGE);
begin
  WriteLn('用户信息:');
  WriteLn('  姓名: ', name);
  WriteLn('  年龄: ', age);
end;

// 5. 布尔默认参数
procedure ProcessData(data: array of Integer; size: Integer; showDetails: Boolean = False; sortByAscending: Boolean = True);
var
  i: Integer;
begin
  if showDetails then
  begin
    WriteLn('处理数据:');
    Write('  原始数据: ');
    for i := 0 to size - 1 do
      Write(data[i], ' ');
    WriteLn;
    
    if sortByAscending then
      WriteLn('  排序方式: 升序')
    else
      WriteLn('  排序方式: 降序');
  end
  else
    WriteLn('处理数据（详情已隐藏）');
end;

// 所有变量声明移到这里
var
  price: Real;
  numbers: array[0..4] of Integer;

// 程序主入口
begin
  WriteLn('=== Pascal 默认参数示例 ===');
  WriteLn;
  
  // 1. 调用带默认参数的过程（使用默认值）
  WriteLn('1. 调用带默认参数的过程:');
  WriteLn('  使用默认 repeatCount 值:');
  DisplayMessage('Hello Pascal!');
  
  WriteLn('  指定 repeatCount 值:');
  DisplayMessage('Hello Pascal!', 3);
  
  WriteLn;
  
  // 2. 调用带多个默认参数的过程
  WriteLn('2. 调用带多个默认参数的过程:');
  WriteLn('  使用所有默认值:');
  DrawRectangle(5, 3);
  
  WriteLn('  指定部分参数:');
  DrawRectangle(6, 4, '#');
  
  WriteLn('  指定所有参数:');
  DrawRectangle(7, 5, '+', True);
  
  WriteLn;
  
  // 3. 调用带默认参数的函数
  WriteLn('3. 调用带默认参数的函数:');
  price := 100.0;
  WriteLn('  原价: ', price:0:2);
  WriteLn('  默认参数计算: ', CalculateDiscountedPrice(price):0:2);
  WriteLn('  10% 折扣: ', CalculateDiscountedPrice(price, 10.0):0:2);
  WriteLn('  10% 折扣 + 5% 税: ', CalculateDiscountedPrice(price, 10.0, 5.0):0:2);
  
  WriteLn;
  
  // 4. 使用常量作为默认参数
  WriteLn('4. 使用常量作为默认参数:');
  WriteLn('  使用所有默认值:');
  DisplayUserInfo();
  
  WriteLn('  指定部分参数:');
  DisplayUserInfo('张三');
  DisplayUserInfo('李四', 25);
  
  WriteLn;
  
  // 5. 布尔默认参数
  WriteLn('5. 布尔默认参数:');
  numbers[0] := 5;
  numbers[1] := 2;
  numbers[2] := 8;
  numbers[3] := 1;
  numbers[4] := 9;
  
  WriteLn('  隐藏详情:');
  ProcessData(numbers, 5);
  
  WriteLn('  显示详情:');
  ProcessData(numbers, 5, True);
  
  WriteLn('  显示详情并降序排列:');
  ProcessData(numbers, 5, True, False);
  
  WriteLn;
  WriteLn('演示了 Pascal 中默认参数的用法');
  
  // 等待用户按键，防止程序窗口立即关闭
  ReadLn;
end.